package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;

import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.service.IDishFlavorService;
import com.sky.service.IDishService;
import com.sky.vo.DishVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import static com.sky.constant.RedisConstants.DISH_KEY;

/**
 * <p>
 * 菜品 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-05-18
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements IDishService {


    @Autowired
    private IDishFlavorService dishFlavorService;


    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Transactional
    @Override
    public void savaWithFlavor(DishDTO dishDTO) {

        //先新增菜品然后再删除缓存

        //1.先将DTO转成实体类
        Dish dish = new Dish();
        BeanUtil.copyProperties(dishDTO, dish);
        //2.设置菜品修改人和创建人的id
        dish.setCreateUser(BaseContext.getCurrentId());
        dish.setUpdateUser(BaseContext.getCurrentId());
        //设置菜品状态（0代表停售，1代表起售）
        dish.setStatus(StatusConstant.ENABLE);//默认起售
        //3.保存菜品基本信息
        this.save(dish);


        //3.保存菜品口味信息
        //3.1获取菜品口味信息
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (!CollectionUtils.isEmpty(flavors)) {
            //3.1.1遍历菜品口味信息，设置菜品id
            ArrayList<DishFlavor> dishFlavors = new ArrayList<>();
            for (DishFlavor df : flavors) {
                //3.2设置菜品id
                df.setDishId(dish.getId());
               /* //3.3保存菜品口味信息
                dishFlavorService.save(df);*/
                dishFlavors.add(df);
            }
            //3.4批量保存菜品口味信息
            dishFlavorService.saveBatch(dishFlavors);

        }
        //删除缓存
        stringRedisTemplate.delete(DISH_KEY + dishDTO.getCategoryId());
    }

    @Override
    public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
        //1.设置分页参数（当前页码和每页展示的记录数)
        int page = dishPageQueryDTO.getPage();//当前页码
        int pageSize = dishPageQueryDTO.getPageSize();//每页展示的记录数
        //2.创建分页对象
        Page<DishVO> p = new Page<>(page, pageSize);
        //3.创建分页条件
        QueryWrapper<Dish> wrapper = new QueryWrapper<>();
        if (dishPageQueryDTO.getName() != null && !dishPageQueryDTO.getName().isEmpty()) {
            wrapper.like("d.name", dishPageQueryDTO.getName());
        }
        if (dishPageQueryDTO.getStatus() != null) {
            wrapper.eq("d.status", dishPageQueryDTO.getStatus());
        }

        if (dishPageQueryDTO.getCategoryId() != null) {
            wrapper.eq("d.category_id", dishPageQueryDTO.getCategoryId());
        }
        wrapper.orderByDesc("d.create_time");


        //4.调用mapper的分页查询方法

        dishMapper.pageQuery(p, wrapper);


        //5.封装返回结果
        return new PageResult(p.getTotal(), p.getRecords());
    }

    @Override
    @Transactional
    public void deleteBatchByIds(List<Long> ids) {


        List<Dish> dishList = dishMapper.selectBatchIds(ids);
        //1.起售中的菜品不能删除
        for (Dish dish : dishList) {
            if (dish.getStatus() == StatusConstant.ENABLE) {
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }
        }
        //2.被套餐关联的菜品不能删除
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getDishId, ids);
        List<SetmealDish> setmealDishList = setmealDishMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(setmealDishList)) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

        //3.删除菜品的时候关联的口味也要删除
       /* for (Long id : ids) {
            //3.1先删除菜品的基本信息
            this.removeById(id);
            //3.2删除菜品口味信息
            LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DishFlavor::getDishId, id);
            dishFlavorMapper.delete(wrapper);
        }*/

        //批量删除菜品基本信息
        this.removeBatchByIds(ids);
        //批量删除菜品口味信息
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DishFlavor::getDishId, ids);
        dishFlavorMapper.delete(wrapper);

        //获取分类id
        for (Dish dish : dishList) {
            //批量删除缓存
            stringRedisTemplate.delete(DISH_KEY + dish.getCategoryId());
        }

    }

    /**
     * 更新菜品信息以及口味信息
     *
     * @param dishDTO
     */

    @Override
    @Transactional
    public void updateWithFlavor(DishDTO dishDTO) {
        //先更新数据库然后再删除缓存
        //1.修改菜品基本信息
        Dish dish = new Dish();
        BeanUtil.copyProperties(dishDTO, dish);
        //2.设置菜品修改人id
        dish.setUpdateUser(BaseContext.getCurrentId());
        //3.构造更新条件
        LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
        //手动更新时间
        dish.setUpdateTime(new Date());
        dish.setUpdateUser(BaseContext.getCurrentId());
        wrapper.eq(Dish::getId, dishDTO.getId());
        wrapper.set(dish.getName() != null && !dish.getName().isEmpty(), Dish::getName, dish.getName())
                .set(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId())
                .set(dish.getPrice() != null, Dish::getPrice, dish.getPrice())
                .set(dish.getImage() != null && !dish.getImage().isEmpty(), Dish::getImage, dish.getImage())
                .set(dish.getDescription() != null && !dish.getDescription().isEmpty(), Dish::getDescription, dish.getDescription())
                .set(dish.getStatus() != null, Dish::getStatus, dish.getStatus());

        this.update(wrapper);
        //4.删除原来的菜品口味信息
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishDTO.getId());
        dishFlavorMapper.delete(queryWrapper);
        //5.添加新的菜品口味信息
        //5.1获取菜品口味信息
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (!CollectionUtils.isEmpty(flavors)) {
            //5.1.1遍历菜品口味信息，设置菜品id
            ArrayList<DishFlavor> dishFlavors = new ArrayList<>();
            for (DishFlavor df : flavors) {
                //5.2设置菜品id
                df.setDishId(dish.getId());
                dishFlavors.add(df);
            }
            //5.3批量保存菜品口味信息
            dishFlavorService.saveBatch(dishFlavors);

        }
        //删除缓存
        stringRedisTemplate.delete(DISH_KEY + dishDTO.getCategoryId());


    }

    @Override
    public List<Dish> listDish(Long categoryId) {
        Dish dish = Dish.builder()
                .categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .build();
        return dishMapper.list(dish);

    }

    @Override
    public void startOrStop(Long id, Integer status) {
        Dish dish = Dish.builder()
                .id(id).status(status)
                .updateUser(BaseContext.getCurrentId())
                .build();

        dish.setUpdateTime(new Date());
        //创建更新条件
        LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Dish::getId, dish.getId())
                .set(dish.getName() != null && !dish.getName().isEmpty(), Dish::getName, dish.getName())
                .set(dish.getStatus() != null, Dish::getStatus, dish.getStatus())
                .set(dish.getUpdateUser() != null, Dish::getUpdateUser, dish.getUpdateUser())
                .set(dish.getUpdateTime() != null, Dish::getUpdateTime, dish.getUpdateTime())
                .set(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId())
                .set(dish.getPrice() != null, Dish::getPrice, dish.getPrice())
                .set(dish.getImage() != null && !dish.getImage().isEmpty(), Dish::getImage, dish.getImage())
                .set(dish.getDescription() != null && !dish.getDescription().isEmpty(), Dish::getDescription, dish.getDescription());
        //执行更新
        this.update(wrapper);
        //删除缓存
        cleanCache(DISH_KEY + "*");
    }


    public void cleanCache(String pattern) {
        //删除所有缓存
        Set<String> keys = stringRedisTemplate.keys(pattern);
        stringRedisTemplate.delete(keys);
    }

}

